0821. 字符的最短距离【简单】
1. 📝 题目描述
- 给你一个字符串
s和一个字符c,且c是s中出现过的字符。 - 返回一个整数数组
answer,其中answer.length == s.length且answer[i]是s中从下标i到离它 最近 的字符c的 距离。 - 两个下标
i和j之间的 距离 为abs(i - j),其中abs是绝对值函数。
示例 1:
- 输入:
s = "loveleetcode", c = "e" - 输出:
[3,2,1,0,1,0,0,1,2,2,1,0] - 解释:
- 字符 'e' 出现在下标 3、5、6 和 11 处(下标从 0 开始计数)。
- 距下标 0 最近的 'e' 出现在下标 3,所以距离为 abs(0 - 3) = 3。
- 距下标 1 最近的 'e' 出现在下标 3,所以距离为 abs(1 - 3) = 2。
- 对于下标 4,出现在下标 3 和下标 5 处的 'e' 都离它最近,但距离是一样的 abs(4 - 3) == abs(4 - 5) = 1。
- 距下标 8 最近的 'e' 出现在下标 6,所以距离为 abs(8 - 6) = 2。
示例 2:
- 输入:
s = "aaab", c = "b" - 输出:
[3,2,1,0]
提示:
1 <= s.length <= 10^4s[i]和c均为小写英文字母- 题目数据保证
c在s中至少出现一次
2. 🎯 s.1 - 两次遍历(从左到右 + 从右到左)
js
/**
* @param {string} s
* @param {character} c
* @return {number[]}
*/
var shortestToChar = function (s, c) {
const n = s.length
const result = new Array(n)
// 从左到右遍历,计算每个位置到左侧最近的c的距离
let prev = -Infinity
for (let i = 0; i < n; i++) {
if (s[i] === c) {
prev = i
}
result[i] = i - prev
}
// 从右到左遍历,计算每个位置到右侧最近的c的距离,并取较小值
prev = Infinity
for (let i = n - 1; i >= 0; i--) {
if (s[i] === c) {
prev = i
}
result[i] = Math.min(result[i], prev - i)
}
return result
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
- 时间复杂度:
,其中 n 是字符串的长度,需要进行两次遍历 - 空间复杂度:
,不考虑结果数组的话,只使用了常数个额外变量 - 算法思路:
- 对于每一个字符
s[i],距离它最近的字符c要么出现在左边,要么出现在右边。 - 可以通过两次遍历分别计算每个位置
i的字符s[i]到其左侧和右侧最近目标字符c的距离,取最小值作为最终结果。
- 对于每一个字符
3. 🎯 s.2 - 中心扩展法
js
/**
* @param {string} s
* @param {character} c
* @return {number[]}
*/
var shortestToChar = function (s, c) {
const n = s.length
const result = new Array(n).fill(Infinity)
// 找到所有c的位置
const positions = []
for (let i = 0; i < n; i++) {
if (s[i] === c) {
positions.push(i)
}
}
// 对每个c的位置,向两边扩展更新距离
for (const pos of positions) {
for (let i = 0; i < n; i++) {
result[i] = Math.min(result[i], Math.abs(i - pos))
}
}
return result
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- 时间复杂度:
,其中 n 是字符串长度,k 是字符 c 的个数 - 空间复杂度:
,不考虑结果数组的话,只使用了常数个额外变量 - 算法思路:
- 【1】找到所有目标字符的位置
- 【2】以每个目标字符作为中心,向左右两边扩展,计算距离
- 【3】取最小值作为最终结果